package com.flag.liutao.modules.role.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.flag.liutao.common.enums.MenuTypeEnum;
import com.flag.liutao.common.enums.SysEnum;
import com.flag.liutao.common.handler.MyException;
import com.flag.liutao.common.utils.TreeUtil;
import com.flag.liutao.modules.role.domain.Menu;
import com.flag.liutao.modules.role.mapper.MenuMapper;
import com.flag.liutao.modules.role.param.MenuParam;
import com.flag.liutao.modules.role.service.IMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.flag.liutao.modules.role.vo.MenuDTO;
import com.flag.liutao.modules.role.vo.MenuVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author godM
 * @since 2022-12-02
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {

    @Autowired
    MenuMapper menuMapper;

    /**
     * 通过分类获取权限列表
     * @param page
     * @param limit
     * @param type
     * @param keyword
     * @return
     */
    @Override
    public Map<String, Object> getMenuList(int page, int limit, String type, String keyword) {

        Map<String,Object> map = new HashMap<>();
        IPage<Menu> iPage = new Page<>(page,limit);
        LambdaQueryWrapper<Menu> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Menu::getType,type).orderByDesc(Menu::getId);
        if(StrUtil.isNotBlank(keyword)){
            lqw.and(lqw1->{
                lqw1.like(Menu::getMenuName,keyword).or().like(Menu::getMenuKey,keyword).or()
                        .like(Menu::getPath,keyword).like(Menu::getIcon,keyword);
            });
        }
        IPage<Menu> pageDB = menuMapper.selectPage(iPage, lqw);
        List<MenuVo> list = pageDB.getRecords().stream().map(menu->{
            MenuVo vo = new MenuVo();
            BeanUtil.copyProperties(menu,vo,"parent");
            if(menu.getPid()!=0L){
                Menu parentDB = menuMapper.selectById(menu.getPid());
                MenuVo parent = new MenuVo();
                BeanUtil.copyProperties(parentDB,parent);
                vo.setParent(parent);
            }
            return vo;
        }).collect(Collectors.toList());
        map.put("content",list);
        map.put("total",pageDB.getTotal());
        return map;
    }

    /**
     * 获取用户的所有菜单权限列表
     * @param id
     * @return
     */
    @Override
    public List<MenuDTO> getUserMenuList(Long id) {
        List<Menu> list =menuMapper.getMenuListById(id,MenuTypeEnum.MENU.getValue());
        return TreeUtil.getTree(getDtoList(list),0L);
    }

    /**
     * 修改权限信息
     * @param param
     */
    @Override
    public void updateMenu(MenuParam param) {
        LambdaQueryWrapper<Menu> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Menu::getMenuKey,param.getMenuKey());
        Menu menuDB = menuMapper.selectOne(lqw);
        if(ObjectUtil.isNotNull(menuDB)&& menuDB.getId()!=param.getId()){
            throw new MyException("权限标识:"+ param.getMenuKey() +"已存在");
        }
        Menu menu = new Menu();
        BeanUtil.copyProperties(param,menu);
        menuMapper.updateById(menu);
    }

    /**
     * 新增权限
     * @param param
     */
    @Override
    public void addMenu(MenuParam param) {
        LambdaQueryWrapper<Menu> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Menu::getMenuKey,param.getMenuKey());
        Menu menuDB = menuMapper.selectOne(lqw);
        if(ObjectUtil.isNotNull(menuDB)){
            throw new MyException("权限标识--"+param.getMenuKey()+"--已被使用！");
        }
        if(MenuTypeEnum.MENU.getValue().equals(param.getType()) && ObjectUtil.isNull(param.getPid())){
            throw new MyException("请为菜单权限类型选择父级菜单");
        }

        Menu menu = new Menu();
        BeanUtil.copyProperties(param,menu);
        menuMapper.insert(menu);
    }

    /**
     * 删除权限
     * @param id
     */
    @Override
    public void delMenu(Long id) {
        menuMapper.deleteById(id);
    }

    /**
     * 获取所有分页信息
     * @return
     */
    @Override
    public Map<String, Object> getMenuList() {
        LambdaQueryWrapper<Menu> lqw1 = new LambdaQueryWrapper<>();
        lqw1.eq(Menu::getType,MenuTypeEnum.POWER.getValue());
        List<Menu> list1 = menuMapper.selectList(lqw1);

        LambdaQueryWrapper<Menu> lqw2 = new LambdaQueryWrapper<>();
        lqw2.eq(Menu::getType,MenuTypeEnum.MENU.getValue()).eq(Menu::getPid,0L).eq(Menu::getStatus, SysEnum.STATUS_1.getValue());
        List<Menu> list2 = menuMapper.selectList(lqw2);

        LambdaQueryWrapper<Menu> lqw3 = new LambdaQueryWrapper<>();
        lqw3.eq(Menu::getType,MenuTypeEnum.MENU.getValue()).ne(Menu::getPid,0L).eq(Menu::getStatus, SysEnum.STATUS_1.getValue());
        List<Menu> list3 = menuMapper.selectList(lqw3);

        Map<String,Object> map = new HashMap<>();
        List<MenuVo> powerList =list1.stream().map(menu -> {
            MenuVo menuVo = new MenuVo();
            BeanUtil.copyProperties(menu,menuVo);
            return menuVo;
        }).collect(Collectors.toList());

        List<MenuVo> rootList =list2.stream().map(menu -> {
            MenuVo menuVo = new MenuVo();
            BeanUtil.copyProperties(menu,menuVo);
            return menuVo;
        }).collect(Collectors.toList());

        List<MenuVo> menuList =list3.stream().map(menu -> {
            MenuVo menuVo = new MenuVo();
            BeanUtil.copyProperties(menu,menuVo);
            return menuVo;
        }).collect(Collectors.toList());

        map.put("powerList",powerList);
        map.put("rootList",rootList);
        map.put("menuList",menuList);
        return map;
    }

    /**
     * 将menuList 转化为MenuDtolist
     * @param menuList
     * @return
     */
    private List<MenuDTO> getDtoList(List<Menu> menuList ){
        List<MenuDTO> list = menuList.stream().map(menu -> {
            MenuDTO menuDTO = new MenuDTO();
            menuDTO.setKey(menu.getMenuKey());
            menuDTO.setLabel(menu.getMenuName());
            menuDTO.setValue(menu.getId());
            menuDTO.setPid(menu.getPid());
            menuDTO.setComponent(menu.getComponent());
            menuDTO.setPath(menu.getPath());
            menuDTO.setIcon(menu.getIcon());
            return menuDTO;
        }).collect(Collectors.toList());
        return list;
    }
}
